/*
	Copyright 2011 Dario Seitel, Sebastian Mayer. All rights reserved.

	Redistribution and use in source and binary forms, with or without modification, are
	permitted provided that the following conditions are met:

	   1. Redistributions of source code must retain the above copyright notice, this list of
		  conditions and the following disclaimer.

	   2. Redistributions in binary form must reproduce the above copyright notice, this list
		  of conditions and the following disclaimer in the documentation and/or other materials
		  provided with the distribution.

	THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY EXPRESS OR IMPLIED
	WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
	FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
	CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
	SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
	ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
	NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
	ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

	The views and conclusions contained in the software and documentation are those of the
	authors and should not be interpreted as representing official policies, either expressed
	or implied, of <copyright holder>.
*/

#ifndef ARIBANODE_H
#define ARIBANODE_H

#include <iostream>
#include <list>
#include <string>
#include <pthread.h>
#include "ariba/ariba.h"
#include "ariba/utility/system/StartupInterface.h"
#include "entities/Shot.h"

#include "mcpo/MCPO.h"

class GameMessage;
class ErrorMessage;
class MoveToMessage;
class PlayerListMessage;
class StringContainerMessage;
class MoveUpDown;
class MessageUpDownTimer;
class MessageRotationTimer;
class GroupPingTimer;
class HostTimeoutTimer;
class MessageEvaluator;

using namespace ariba;
using namespace std;
using ariba::utility::StartupInterface;
using ariba::services::mcpo::MCPO;
using std::string;

class AribaNode:
	public MCPO::ReceiverInterface,
	public NodeListener,
	public CommunicationListener,
	public StartupInterface,
	public SideportListener {
public:
	static bool isInitiator;
	static bool isHost;

	AribaNode();
	virtual void sendUpDownKeyMessage(bool upDown);
	virtual void stopUpDownKeyMessage(bool upDown);
	virtual void sendRotationMessage(bool rightLeft);
	virtual void stopRotationMessage(bool rightLeft);
	virtual void sendShot(Shot* shot);
	virtual void publish();

	//own group function
	virtual void JoinGroup(int groupID);
	virtual void LeaveGroup(int groupID);
	virtual bool IsGroupJoined(int groupID);

	//timer events
	virtual void MessageUpDownTimerEvent();
	virtual void MessageRotationTimerEvent();
	virtual void GroupPingTimerEvent();
	virtual void HostTimeoutTimerEvent();

	virtual void connectToRegion(int groupID);
	virtual void connectToGame(int groupID);

	virtual void sendMessageToGroup(GameMessage* msg, int groupID);
	virtual void sendMessageToNode(GameMessage msg, ariba::utility::NodeID nodeID);
	virtual void sendMessageToRegions(GameMessage* msg);

	virtual Node& getNode();

	virtual bool isReady();

	static ServiceID ARIBANODE_SERVICEID;

protected:
	// node listener interface
	virtual void onJoinCompleted( const SpoVNetID& vid );
	virtual void onJoinFailed( const SpoVNetID& vid );
	virtual void onLeaveCompleted( const SpoVNetID& vid );
	virtual void onLeaveFailed( const SpoVNetID& vid );

	// communication listener interface
	virtual void onMessage(const DataMessage& msg, const ariba::NodeID& remote, const ariba::LinkID& lnk = ariba::LinkID::UNSPECIFIED);

	// startup wrapper interface
	virtual void startup();
	virtual void shutdown();

	// the dht message handler (for answers to get() requests)
	virtual void onKeyValue( const Data& key, const vector<Data>& value );

	AribaModule* ariba;

	// receiver interface
	virtual	void receiveData( const DataMessage& msg );
	virtual void serviceIsReady();

private:

	// the ariba module
	Node* node;
	MCPO* mcpo;

	ariba::NodeID myNodeId;

	string hostName;
	ariba::NodeID hostID;

	pthread_t guiThread;

	MessageUpDownTimer* upDownTimer;
	MessageRotationTimer* rotationTimer;
	GroupPingTimer* groupPingTimer;
	HostTimeoutTimer* hostTimeoutTimer;
	int lastHostMessageTime;
	string nextHostName;
	bool ready;

	MessageEvaluator* messageEvaluator;

	static bool running;
	static int TimerMoveIntervall;
	static int GroupPingTimerIntervall;
	static int HostTimeoutTimerIntervall;
	list<int> groups;

	int publisherIdentifier;
};


#endif /* ARIBANODE_H_ */
